home *** CD-ROM | disk | FTP | other *** search
/ Best of Shareware / Best of PC Windows Shareware 1.0 - Wayzata Technology (7111) (1993).iso / mac / DOS / MATH / FSULTRA1 / ULTRXCOD.INC < prev   
Text File  |  1992-06-18  |  9KB  |  375 lines

  1. comment ! 
  2. FSU - ULTRA    The greatest random number generator that ever was
  3.         or ever will be.  Way beyond Super-Duper.
  4.         (Just kidding, but we think its a good one.)
  5.  
  6. Authors:    Arif Zaman (arif@stat.fsu.edu) and
  7.         George Marsaglia (geo@stat.fsu.edu).
  8.  
  9. Date:        27 May 1992
  10.  
  11. Version:    1.05
  12.  
  13. Copyright:    To obtain permission to incorporate this program into
  14.         any commercial product, please contact the authors at
  15.         the e-mail address given above or at
  16.  
  17.         Department of Statistics and
  18.         Supercomputer Computations Research Institute
  19.         Florida State University
  20.         Tallahassee, FL 32306.
  21.  
  22. See Also:    README        for a brief description
  23.         ULTRA.DOC    for a detailed description
  24.  
  25. -----------------------------------------------------------------------
  26. .386
  27. ; This file is included in after a header file which defines
  28. ; language dependent elements. (see ultra.doc for details)
  29. ;
  30. rinit    proc        ; INITIALIZE SEED ARRAY ========================
  31.     Enter2arg
  32. ;
  33. ; On entry:
  34. ;    eax and ebx contain congruential and shift-register seeds
  35. ;
  36. ; On exit:
  37. ;    The swbb array is set using the McGill Super-Duper generator,
  38. ;    which is a mix of a congruential and shift-register sequence.
  39. ;    Flags and counters are reset.
  40. ;
  41. ; Registers Clobbered:  AX,BX,CX,DX,SI,DI.
  42. ;
  43. ; Algorithm:
  44. ;    Starting from lsm of x[0] to the msb of x[N-1], each bit is
  45. ;    formed using the sign bit of the xor of a congruential generator
  46. ;    with seed ConX and a shift register sequence with seed ShrX.
  47. ;
  48. ; Register usage
  49. ;   eax contains congruential seed
  50. ;   ebx contains the shift-register seed
  51. ;   cx contains count for two loops
  52. ;      ch counts the outer loop (for each byte of the array x)
  53. ;      cl counts for each bit of x[i]
  54. ;   es:di point to where x[i] is
  55. ;   edx is a temporary register
  56. ;
  57.     mov ch,N*4
  58.     mov di,offset swbseed    ; do loop for x[0], ... , x[4*n] (bytes)
  59. nextbyte:
  60.       mov cl,8
  61. nextbit:
  62.     mov  edx,dword ptr 69069
  63.     mul  edx
  64.  
  65.     mov  edx,ebx
  66.     shr  edx,15
  67.     xor  ebx,edx
  68.     mov  edx,ebx
  69.     shl  edx,17
  70.     xor  ebx,edx
  71.  
  72.     mov  edx,eax
  73.     xor  edx,ebx
  74.     rcl  edx,1
  75.  
  76.     rcr  byte ptr [di],1   ; shift it into the answer
  77.     dec  cl
  78.     jnz  nextbit
  79.     inc  di             ; Store the answer in swbb[i]
  80.     dec ch
  81.     jnz nextbyte
  82. ;
  83. ; reset all counters, flags etc. and return.
  84. ;
  85.     xor bx,bx
  86.     mov swb32.c,bx
  87.     mov swb16.c,bx
  88.     mov swb8.c,bx
  89.     mov swb1.c,bx
  90.     mov flags,bl
  91.     mov congx,eax
  92.     Exit2arg
  93. rinit    endp
  94.  
  95. SWBfill    proc near    ; SUBTRACT-WITH-BORROW ========================
  96. ;
  97. ;  On Entry:
  98. ;     DS should point to the data segment.
  99. ;     BX points to the array where the results will be stored (swb??.c)
  100. ;
  101. ;  On Exit:
  102. ;     The swbseed array contains all new values computed by the
  103. ;     subtract-with-carry generator. The CARRY byte contains the
  104. ;     state of the carry flag due to the last subtraction.
  105. ;     swb??.x contians the seed xored with a congurential.
  106. ;
  107. ;  Registers Clobbered: AX,BX,CX,DX,SI,DI
  108. ;
  109. ;  Algorithm:
  110. ;     The following subtractions are performed from right to left.
  111. ;     The carry propagates as though these were two long numbers,
  112. ;     with each x[i] being a `digit' in base 2^32.
  113. ;
  114. ;        x[12] ...  x[ 0]      x[36] ...  x[13]
  115. ;       -x[36] ... -x[24]     -x[23] ... -x[ 0]
  116. ;       ---------------------------------------
  117. ;        x[36] ...  x[24]      x[23] ...  x[ 0]
  118. ;
  119. ;
  120. ;    for a bigger table, it could be done in three steps by:
  121. ;
  122. ;     x[ 12] ...  x[   0]  :  x[N-1 ]  x[N-24]  :   x[N-25] ...  x[13]
  123. ;    -x[N-1] ... -x[N-13]  :  x[N-14] -x[N-37]  :  -x[N-38] ... -x[ 0]
  124. ;    ----------------------:--------------------:---------------------
  125. ;     x[ 36] ...  x[  24]  :  x[13  ]  x[0   ]  :   x[N-1 ] ...  x[37]
  126. ;
  127. ;     The x's also could be considered as pairs of base 16 digits,
  128. ;     so that x[i] is the pair y[2i+1]y[2i]. This allows us to use
  129. ;     only 16 bit subtractions with carry, perfectly suited for all
  130. ;     80x86 processors. The same idea could be extended for machines
  131. ;     with only eight bit, or even only 1 bit arithmetic.
  132. ;
  133.     EnterFill
  134.     mov ah,byte ptr flags   ; set carry flag to what it was the
  135.     sahf                    ; last time we exited this routine
  136.  
  137.     mov cx,24               ; will do first loop 24 times
  138.     mov ax,ds
  139.     mov es,ax
  140.     mov si,offset(swbseed)+13*4; set up ds:si -> x[13]
  141.     mov di,offset(swbseed)     ; set up es:di -> x[0]
  142.  
  143. loop1:  ; On a 80386, the instructions `lodsd', `stosd' and `loop'
  144.     ; all change registers automatically as noted in parentheses
  145.  
  146.     lodsd                   ;    ax = x[i+13]     ( si = si+4 )
  147.     sbb eax,[di]            ;    ax = ax-x[i]-carry
  148.     stosd                   ;    y[i] = ax        ( di = di+4 )
  149.     loop loop1              ; loop for i=0..47    ( cx = cx-1 )
  150.  
  151.     mov cx,13               ; will do next loop 13 times
  152.     mov si,offset(swbseed)  ; set up ds:si -> x[0]
  153.                                 ; es:di is already set up
  154. loop2:
  155.     lodsd                   ;    ax = x[i-24]     ( si = si+4 )
  156.     sbb eax,[di]            ;    ax = ax-x[i]-carry
  157.     stosd                   ;    x[i] = ax        ( di = di+4 )
  158.     loop loop2              ; loop for i=48..73   ( cx = cx-1 )
  159.  
  160.     lahf
  161.     mov byte ptr flags,ah   ; save carry flag for next time
  162. ;
  163. ; XOR the elements of swbb with a congruential generator and put the
  164. ; result in swbnn.x, reset the counter and the pointer.
  165. ;
  166.  
  167.     mov  di,bx
  168.     mov  [bx-4],bx
  169.     mov  si,offset(swbseed)
  170.     mov  cx,N
  171. IFNDEF fast
  172.     mov  eax,congx
  173.     mov  ebx,69069
  174. loopc:  mul  ebx
  175.     mov  edx,eax
  176.     lodsd
  177.     xor  eax,edx
  178.     stosd
  179.     mov  eax,edx
  180.     loop loopc
  181.     mov  congx,eax
  182. ELSE
  183.     rep  movsd
  184. ENDIF
  185.     ExitFill
  186. SWBfill    endp
  187.  
  188. ; Random Number procedures ============================================
  189. ;
  190. CheckFill MACRO bits,bytes,count
  191.     local ok
  192.     dec    bits.c
  193.     jns    ok
  194.         mov   bx,offset(bits.x)
  195.         call  SWBfill
  196.         mov   bits.c,count-1
  197. ok:    mov    bx,bits.p
  198.     add    bits.p,bytes
  199. ENDM
  200.  
  201. i32bit proc
  202.     EnterProcedure
  203.     CheckFill swb32,4,N
  204.     mov    ax,[bx]
  205.     mov    dx,[bx+2]
  206.     DwordFn
  207.     ExitProcedure
  208. i32bit endp
  209.  
  210. i31bit proc
  211.     EnterProcedure
  212.     CheckFill  swb32,4,N
  213.     mov    ax,[bx]
  214.     mov    dx,[bx+2]
  215.     and    dh,7Fh
  216.     DwordFn
  217.     ExitProcedure
  218. i31bit endp
  219.  
  220. i16bit proc
  221.     EnterProcedure
  222.     CheckFill  swb16,2,2*N
  223.     mov    ax,[bx]
  224.     WordFn
  225.     ExitProcedure
  226. i16bit endp
  227.  
  228. i15bit proc
  229.     EnterProcedure
  230.     CheckFill  swb16,2,2*N
  231.     mov    ax,[bx]
  232.     and  ah,7Fh
  233.     WordFn
  234.     ExitProcedure
  235. i15bit endp
  236.  
  237. i8bit  proc
  238.     EnterProcedure
  239.     CheckFill  swb8,1,4*N
  240.     mov    al,[bx]
  241.     ByteFn
  242.     ExitProcedure
  243. i8bit  endp
  244.  
  245. i7bit proc
  246.     EnterProcedure
  247.     CheckFill  swb8,1,4*N
  248.     mov    al,[bx]
  249.     and al,7Fh
  250.     ByteFn
  251.     ExitProcedure
  252. i7bit  endp
  253.  
  254. i1bit  proc
  255.     EnterProcedure di
  256.     dec    swb1.c
  257.     jns    ok1
  258.         CheckFill  swb32,4,N    ; do an i32bit
  259.         mov      dx,[bx+2]
  260.         mov   bx,[bx]        ; with the answer in dx:bx
  261.         mov   swb1.c,31
  262.         mov   di,offset(swb1.x)
  263.         mov   swb1.p,di
  264.         mov   ax,ds
  265.         mov   es,ax
  266.  
  267.         mov   cx,16
  268. stosb1:        mov      al,1
  269.         and   al,bl
  270.         stosb
  271.         shr      bx,1
  272.         loop  stosb1
  273.  
  274.         mov      cl,16
  275. stosb2:        mov   al,1
  276.         and   al,dl
  277.         stosb
  278.         shr   dx,1
  279.         loop  stosb2
  280. ok1:    mov    bx,swb1.p
  281.     inc    swb1.p
  282.     mov    al,[bx]
  283.     ByteFn
  284.     ExitProcedure di
  285. i1bit  endp
  286.  
  287. uni proc
  288.     EnterProcedure
  289.     fild    neg31
  290.     CheckFill    swb32,4,N
  291.     and    byte ptr [bx+3],7Fh
  292.     jnz    oku
  293.         mov   eax,[bx]
  294.         mov   tmpdhi,eax
  295.         CheckFill  swb32,4,N
  296.         mov   eax,[bx]
  297.         mov   tmpdlo,eax
  298.         fild  tmpq
  299.         jmp   uxit
  300. oku:    fild    dword ptr [bx]
  301. uxit:    fscale
  302.     fstp    st(1)
  303.     RealFn
  304.     ExitProcedure
  305. uni endp
  306.  
  307. vni proc
  308.     EnterProcedure
  309.     fild    neg31
  310.     CheckFill    swb32,4,N
  311.     test    byte ptr [bx+3],0FFh
  312.     jnz    okv
  313.         mov   eax,[bx]
  314.         mov   tmpdhi,eax
  315.         CheckFill  swb32,4,N
  316.         mov   eax,[bx]
  317.         mov   tmpdlo,eax
  318.         fild  tmpq
  319.         jmp   vxit
  320. okv:    fild    dword ptr [bx]
  321. vxit:    fscale
  322.     fstp    st(1)
  323.     RealFn
  324.     ExitProcedure
  325. vni endp
  326.  
  327. duni proc
  328.     EnterProcedure
  329.     fild    neg63
  330.     CheckFill    swb32,4,N
  331.     dec    swb32.c
  332.     jns    okdu
  333.         mov   eax,swb32.x[4*N-4]
  334.         mov   tmpdlo,eax
  335.         mov   bx,offset(swb32.x)
  336.         call  SWBfill
  337.         mov   swb32.c,N-1
  338.         mov      eax,swb32.x
  339.         mov   tmpdhi,eax
  340.         and   byte ptr [tmpq+7],7Fh
  341.         fild  tmpq
  342.         jmp   duxit
  343. okdu:    and    byte ptr [bx+7],7Fh
  344.     fild    qword ptr [bx]
  345. duxit:    add    swb32.p,4
  346.     fscale
  347.     fstp    st(1)
  348.     DoubleFn
  349.     ExitProcedure
  350. duni endp
  351.  
  352. dvni proc
  353.     EnterProcedure
  354.     fild    neg63
  355.     CheckFill  swb32,4,N
  356.     dec    swb32.c
  357.     jns    okdv
  358.         mov   eax,swb32.x[4*N-4]
  359.         mov   tmpdlo,eax
  360.         mov   bx,offset(swb32.x)
  361.         call  SWBfill
  362.         mov   swb32.c,N-1
  363.         mov   eax,swb32.x
  364.         mov   tmpdhi,eax
  365.         fild  tmpq
  366.         jmp   dvxit
  367. okdv:    fild    qword ptr [bx]
  368. dvxit:    add    swb32.p,4
  369.     fscale
  370.     fstp    st(1)
  371.     DoubleFn
  372.     ExitProcedure
  373. dvni endp
  374.